package com.swing.sky.web.generator.util;

import java.util.List;

import org.apache.velocity.VelocityContext;

import com.swing.sky.web.generator.config.GenConfig;
import com.swing.sky.web.generator.constant.ModuleConstants;
import com.swing.sky.web.generator.domain.GenColumn;
import com.swing.sky.web.generator.domain.Module;
import com.swing.sky.web.generator.domain.ModuleHouse;

/**
 * @author swing
 */
public class VelocityContextBuilder {
    /**
     * 使用适配器模式找到对应的上下文
     */
    public static VelocityContext buildVelocityContext(List<ModuleHouse> moduleHouses, ModuleHouse moduleHouse,
            Module module) {
        String name = module.getModuleName();
        if (name.equals(ModuleConstants.DOMAIN)) {
            return buildDO(moduleHouse, module);
        }
        if (name.equals(ModuleConstants.BASIC_DAO)) {
            return buildXBasicDAO(module);
        }
        if (name.equals(ModuleConstants.BASIC_SERVICE)) {
            return buildXBasicService(moduleHouse, module);
        }
        if (name.equals(ModuleConstants.DAO_BASIC)) {
            return buildXDAOBasic(moduleHouse, module);
        }
        if (name.equals(ModuleConstants.SERVICE_SUPER)) {
            return buildServiceBasic(moduleHouse, module);
        }
        if (name.equals(ModuleConstants.MAPPER)) {
            return buildXMapper(moduleHouse, module);
        }
        if (name.equals(ModuleConstants.SERVICE)) {
            return buildService(moduleHouse, module);
        }
        if (name.equals(ModuleConstants.RELATE_DAO)) {
            return buildRelateDao(module, moduleHouse);
        }
        if (name.equals(ModuleConstants.RELATE_MAPPER)) {
            return buildRelateMapper(module, moduleHouse);
        }

        if (name.equals(ModuleConstants.BASIC_DOMAIN)) {
            return buildBasicDO(moduleHouse, module);
        }
        if (name.equals(ModuleConstants.DOMAIN_BASIC)) {
            return buildDOBasic(moduleHouse, module);
        }
        if (name.equals(ModuleConstants.BASIC_MAPPER)) {
            return buildXBasicMapper(module, moduleHouse);
        }
        if (name.equals(ModuleConstants.DAO)) {
            return buildXDAO(moduleHouse, module);
        }
        if (name.equals(ModuleConstants.MAPPER_BASIC)) {
            return buildXMapperBasic(moduleHouse, module);
        }
        if (name.equals(ModuleConstants.SERVICE_IMPL)) {
            return buildServiceImpl(moduleHouse, module);
        }
        if (name.equals(ModuleConstants.BASIC_LINK_DAO)) {
            return buildBasicLinkDAO(module);
        }
        if (name.equals(ModuleConstants.DAO_LINK)) {
            ModuleHouse leftModule = null;
            ModuleHouse rightModule = null;
            for (ModuleHouse house : moduleHouses) {
                if (house.getTableName().equalsIgnoreCase(moduleHouse.getLeftHouseName())) {
                    leftModule = house;
                }
                if (house.getTableName().equalsIgnoreCase(moduleHouse.getRightHouseName())) {
                    rightModule = house;
                }
            }
            assert leftModule != null;
            return buildDAOLink(leftModule, module, rightModule, moduleHouse);
        }
        if (name.equals(ModuleConstants.LINK_MAPPER)) {
            ModuleHouse leftModule = null;
            ModuleHouse rightModule = null;
            for (ModuleHouse house : moduleHouses) {
                if (house.getTableName().equalsIgnoreCase(moduleHouse.getLeftHouseName())) {
                    leftModule = house;
                }
                if (house.getTableName().equalsIgnoreCase(moduleHouse.getRightHouseName())) {
                    rightModule = house;
                }
            }
            assert leftModule != null;
            return buildLinkMapper(leftModule, module, rightModule, moduleHouse);
        }
        return null;
    }

    public static VelocityContext buildLinkMapper(ModuleHouse leftModule, Module module,
            ModuleHouse rightModule, ModuleHouse moduleHouse) {
        VelocityContext velocityContext = new VelocityContext();
        for (Module m : leftModule.getModules()) {
            if (m.getModuleName().equalsIgnoreCase(ModuleConstants.DOMAIN)
                    || m.getModuleName().equalsIgnoreCase(ModuleConstants.DOMAIN_BASIC)) {
                velocityContext.put("leftDoPackage", m.getPackageName() + "." + m.getFileName());
            }
            if (m.getModuleName().equalsIgnoreCase(ModuleConstants.DAO)
                    || m.getModuleName().equalsIgnoreCase(ModuleConstants.DAO_BASIC)) {
                velocityContext.put("leftDaoPackage", m.getPackageName() + "." + m.getFileName());
            }
        }
        for (Module m : rightModule.getModules()) {
            if (m.getModuleName().equalsIgnoreCase(ModuleConstants.DOMAIN)
                    || m.getModuleName().equalsIgnoreCase(ModuleConstants.DOMAIN_BASIC)) {
                velocityContext.put("rightDoPackage", m.getPackageName() + "." + m.getFileName());
            }
            if (m.getModuleName().equalsIgnoreCase(ModuleConstants.DAO)
                    || m.getModuleName().equalsIgnoreCase(ModuleConstants.DAO_BASIC)) {
                velocityContext.put("rightDaoPackage", m.getPackageName() + "." + m.getFileName());
            }
        }
        for (Module module1 : moduleHouse.getModules()) {
            if (module1.getModuleName().equalsIgnoreCase(ModuleConstants.DOMAIN)) {
                velocityContext.put("doPackage", module1.getPackageName() + "." + module1.getFileName());
            }
            if (module1.getModuleName().equalsIgnoreCase(ModuleConstants.DAO_LINK)) {
                velocityContext.put("daoLinkPackageName", module1.getPackageName() + "." + module1.getFileName());
            }
        }
        velocityContext.put("columns", moduleHouse.getColumns());
        velocityContext.put("tableName", moduleHouse.getTableName());
        velocityContext.put("oneColumn", moduleHouse.getColumns().get(0).getColumnName());
        velocityContext.put("twoColumn", moduleHouse.getColumns().get(1).getColumnName());
        velocityContext.put("oneProperty", moduleHouse.getColumns().get(0).getPropertyName());
        velocityContext.put("twoProperty", moduleHouse.getColumns().get(1).getPropertyName());
        return velocityContext;
    }

    public static VelocityContext buildDAOLink(ModuleHouse leftModule, Module module,
            ModuleHouse rightModule, ModuleHouse moduleHouse) {
        VelocityContext velocityContext = new VelocityContext();
        velocityContext.put("packageName", module.getPackageName());
        velocityContext.put("className", module.getFileName());
        for (Module m : leftModule.getModules()) {
            if (m.getModuleName().equalsIgnoreCase(ModuleConstants.DOMAIN)
                    || m.getModuleName().equalsIgnoreCase(ModuleConstants.DOMAIN_BASIC)) {
                velocityContext.put("leftDoPackage", m.getPackageName() + "." + m.getFileName());
                velocityContext.put("leftDoClassName", m.getFileName());
            }
        }
        for (Module m : rightModule.getModules()) {
            if (m.getModuleName().equalsIgnoreCase(ModuleConstants.DOMAIN)
                    || m.getModuleName().equalsIgnoreCase(ModuleConstants.DOMAIN_BASIC)) {
                velocityContext.put("rightDoPackage", m.getPackageName() + "." + m.getFileName());
                velocityContext.put("rightDoClassName", m.getFileName());
            }
        }
        for (Module module1 : moduleHouse.getModules()) {
            if (module1.getModuleName().equalsIgnoreCase(ModuleConstants.DOMAIN)) {
                velocityContext.put("doPackage", module1.getPackageName() + "." + module1.getFileName());
                velocityContext.put("doClassName", module1.getFileName());
            }
            if (module1.getModuleName().equalsIgnoreCase(ModuleConstants.BASIC_LINK_DAO)) {
                velocityContext.put("basicLinkDAOPackageName", module1.getPackageName() + "." + module1.getFileName());
                velocityContext.put("basicLinkDAOClassName", module1.getFileName());
            }
        }
        return velocityContext;
    }

    public static VelocityContext buildRelateDao(Module module, ModuleHouse moduleHouse) {
        VelocityContext velocityContext = new VelocityContext();
        for (Module module1 : moduleHouse.getModules()) {
            if (module1.getModuleName().equalsIgnoreCase(ModuleConstants.DOMAIN)
                    || module1.getModuleName().equalsIgnoreCase(ModuleConstants.DOMAIN_BASIC)) {
                velocityContext.put("DOPackageName", module1.getPackageName() + "." + module1.getFileName());
                velocityContext.put("DOClassName", module1.getFileName());
            }
            if (module1.getModuleName().equalsIgnoreCase(ModuleConstants.BASIC_DAO)) {
                velocityContext.put("DAOPackageName", module1.getPackageName() + "." + module1.getFileName());
                velocityContext.put("DAOClassName", module1.getFileName());
            }
        }
        velocityContext.put("keyClassType", moduleHouse.getPrimaryKey().getPropertyType());
        velocityContext.put("author", GenConfig.getAuthor());
        velocityContext.put("uniqueIndexs", moduleHouse.getUniqueIndexs());
        velocityContext.put("className", module.getFileName());
        velocityContext.put("packageName", module.getPackageName());
        velocityContext.put("tableComment", moduleHouse.getTableComment());
        return velocityContext;
    }

    public static VelocityContext buildRelateMapper(Module module, ModuleHouse moduleHouse) {
        VelocityContext velocityContext = new VelocityContext();
        for (Module module1 : moduleHouse.getModules()) {
            if (module1.getModuleName().equalsIgnoreCase(ModuleConstants.DOMAIN)) {
                velocityContext.put("do", module1.getPackageName() + "." + module1.getFileName());
            }
            if (module1.getModuleName().equalsIgnoreCase(ModuleConstants.RELATE_DAO)) {
                velocityContext.put("dao", module1.getPackageName() + "." + module1.getFileName());
            }
        }
        velocityContext.put("keyJdbcType", moduleHouse.getPrimaryKey().getJdbcType());
        velocityContext.put("keyClassType", moduleHouse.getPrimaryKey().getPropertyType());
        velocityContext.put("tableName", moduleHouse.getTableName());
        velocityContext.put("columns", moduleHouse.getColumns());
        velocityContext.put("commonColumns", moduleHouse.getCommonColumns());
        velocityContext.put("uniqueIndexs", moduleHouse.getUniqueIndexs());
        List<GenColumn> collect = MapUtils.filterBasicColumns(moduleHouse.getColumns());
        velocityContext.put("collect", collect);
        return velocityContext;
    }

    /**
     * 构建渲染BasicDAO.java.vm需要的上下文
     */
    public static VelocityContext buildBasicLinkDAO(Module module) {
        VelocityContext velocityContext = new VelocityContext();
        velocityContext.put("packageName", module.getPackageName());
        velocityContext.put("className", module.getFileName());
        return velocityContext;
    }

    /**
     * 构建渲染ServiceImpl.java.vm需要的上下文
     */
    public static VelocityContext buildServiceImpl(ModuleHouse moduleHouse, Module module) {
        VelocityContext velocityContext = new VelocityContext();
        for (Module module1 : moduleHouse.getModules()) {
            if (module1.getModuleName().equalsIgnoreCase(ModuleConstants.SERVICE)
                    || module1.getModuleName().equalsIgnoreCase(ModuleConstants.SERVICE_SUPER)) {
                velocityContext.put("ServicePackageName", module1.getPackageName() + "." + module1.getFileName());
                velocityContext.put("ServiceClassName", module1.getFileName());
            }
            if (module1.getModuleName().equalsIgnoreCase(ModuleConstants.DOMAIN)
                    || module1.getModuleName().equalsIgnoreCase(ModuleConstants.DOMAIN_BASIC)) {
                velocityContext.put("DOPackageName", module1.getPackageName() + "." + module1.getFileName());
                velocityContext.put("DOClassName", module1.getFileName());
                velocityContext.put("DOPropertyName", MapUtils.toLowerCaseName(module1.getFileName()));
            }
            if (module1.getModuleName().equalsIgnoreCase(ModuleConstants.DAO)
                    || module1.getModuleName().equalsIgnoreCase(ModuleConstants.DAO_BASIC)) {
                velocityContext.put("DAOPackageName", module1.getPackageName() + "." + module1.getFileName());
                velocityContext.put("DAOClassName", module1.getFileName());
                velocityContext.put("DAOPropertyName", MapUtils.toLowerCaseName(module1.getFileName()));
            }
        }
        velocityContext.put("author", GenConfig.getAuthor());
        velocityContext.put("className", module.getFileName());
        velocityContext.put("packageName", module.getPackageName());
        velocityContext.put("tableComment", moduleHouse.getTableComment());
        return velocityContext;
    }

    /**
     * 构建渲染Service_BASIC.java.vm需要的上下文
     */
    public static VelocityContext buildServiceBasic(ModuleHouse moduleHouse, Module module) {
        VelocityContext velocityContext = new VelocityContext();
        for (Module module1 : moduleHouse.getModules()) {
            if (module1.getModuleName().equalsIgnoreCase(ModuleConstants.DOMAIN)
                    || module1.getModuleName().equalsIgnoreCase(ModuleConstants.DOMAIN_BASIC)) {
                velocityContext.put("doImport", module1.getPackageName() + "." + module1.getFileName());
                velocityContext.put("doClass", module1.getFileName());
            }
            if (module1.getModuleName().equalsIgnoreCase(ModuleConstants.DAO_BASIC)) {
                velocityContext.put("daoImport", module1.getPackageName() + "." + module1.getFileName());
                velocityContext.put("daoClass", module1.getFileName());
            }
        }
        velocityContext.put("keyClassType", moduleHouse.getPrimaryKey().getPropertyType());
        velocityContext.put("author", GenConfig.getAuthor());
        velocityContext.put("className", module.getFileName());
        velocityContext.put("packageName", module.getPackageName());
        velocityContext.put("tableComment", moduleHouse.getTableComment());
        velocityContext.put("uniqueIndexs", moduleHouse.getUniqueIndexs());
        return velocityContext;
    }

    /**
     * 构建渲染Service.java.vm需要的上下文
     */
    public static VelocityContext buildService(ModuleHouse moduleHouse, Module module) {
        VelocityContext velocityContext = new VelocityContext();
        for (Module module1 : moduleHouse.getModules()) {
            if (module1.getModuleName().equalsIgnoreCase(ModuleConstants.SERVICE_SUPER)) {
                velocityContext.put("serviceSuperImport", module1.getPackageName() + "." + module1.getFileName());
                velocityContext.put("serviceSuperClass", module1.getFileName());
            }
        }
        velocityContext.put("author", GenConfig.getAuthor());
        velocityContext.put("className", module.getFileName());
        velocityContext.put("packageName", module.getPackageName());
        velocityContext.put("tableComment", moduleHouse.getTableComment());
        return velocityContext;
    }

    /**
     * 构建渲染BasicDO.java.vm需要的上下文
     */
    public static VelocityContext buildBasicDO(ModuleHouse house, Module module) {
        VelocityContext velocityContext = new VelocityContext();
        velocityContext.put("packageName", module.getPackageName());
        velocityContext.put("author", GenConfig.getAuthor());
        velocityContext.put("className", module.getFileName());
        velocityContext.put("columns", MapUtils.getBasicColumns(house.getColumns()));
        return velocityContext;
    }

    /**
     * 构建渲染DO.java.vm需要的上下文
     */
    public static VelocityContext buildDO(ModuleHouse house, Module module) {
        VelocityContext velocityContext = new VelocityContext();
        velocityContext.put("packageName", module.getPackageName());
        velocityContext.put("tableName", house.getTableName());
        velocityContext.put("tableComment", house.getTableComment());
        velocityContext.put("author", GenConfig.getAuthor());
        velocityContext.put("className", module.getFileName());
        velocityContext.put("columns", house.getColumns());
        boolean isDateImport = false;
        for (GenColumn columns : house.getColumns()) {
            if (columns.getPropertyType().equalsIgnoreCase("LocalDateTime")) {
                isDateImport = true;
                break;
            }
        }
        velocityContext.put("isDateImport", isDateImport);
        return velocityContext;
    }

    /**
     * 构建渲染DO_BASIC.java.vm需要的上下文
     */
    public static VelocityContext buildDOBasic(ModuleHouse house, Module module) {
        List<GenColumn> collect = MapUtils.filterBasicColumns(house.getColumns());
        VelocityContext velocityContext = new VelocityContext();
        for (Module module1 : house.getModules()) {
            if (module1.getModuleName().equalsIgnoreCase(ModuleConstants.BASIC_DOMAIN)) {
                velocityContext.put("DOPackageName", module1.getPackageName() + "." + module1.getFileName());
                velocityContext.put("DOClassName", module1.getFileName());
            }
        }
        velocityContext.put("packageName", module.getPackageName());
        velocityContext.put("tableName", house.getTableName());
        velocityContext.put("tableComment", house.getTableComment());
        velocityContext.put("author", GenConfig.getAuthor());
        velocityContext.put("className", module.getFileName());
        velocityContext.put("columns", collect);
        return velocityContext;
    }

    /**
     * 构建渲染DAO_BASIC.java.vm需要的上下文
     */
    public static VelocityContext buildXDAOBasic(ModuleHouse moduleHouse, Module module) {
        VelocityContext velocityContext = new VelocityContext();
        for (Module module1 : moduleHouse.getModules()) {
            if (module1.getModuleName().equalsIgnoreCase(ModuleConstants.DOMAIN)
                    || module1.getModuleName().equalsIgnoreCase(ModuleConstants.DOMAIN_BASIC)) {
                velocityContext.put("DOPackageName", module1.getPackageName() + "." + module1.getFileName());
                velocityContext.put("DOClassName", module1.getFileName());
            }
            if (module1.getModuleName().equalsIgnoreCase(ModuleConstants.BASIC_DAO)) {
                velocityContext.put("DAOPackageName", module1.getPackageName() + "." + module1.getFileName());
                velocityContext.put("DAOClassName", module1.getFileName());
            }
        }
        velocityContext.put("keyClassType", moduleHouse.getPrimaryKey().getPropertyType());
        velocityContext.put("author", GenConfig.getAuthor());
        velocityContext.put("uniqueIndexs", moduleHouse.getUniqueIndexs());
        velocityContext.put("className", module.getFileName());
        velocityContext.put("packageName", module.getPackageName());
        velocityContext.put("tableComment", moduleHouse.getTableComment());
        return velocityContext;
    }

    /**
     * 构建渲染DAO.java.vm需要的上下文
     */
    public static VelocityContext buildXDAO(ModuleHouse moduleHouse, Module module) {
        VelocityContext velocityContext = new VelocityContext();
        for (Module module1 : moduleHouse.getModules()) {
            if (module1.getModuleName().equalsIgnoreCase(ModuleConstants.DOMAIN)) {
                velocityContext.put("DOPackageName", module1.getPackageName() + "." + module1.getFileName());
                velocityContext.put("DOClassName", module1.getFileName());
            }
        }
        velocityContext.put("author", GenConfig.getAuthor());
        velocityContext.put("className", module.getFileName());
        velocityContext.put("packageName", module.getPackageName());
        velocityContext.put("tableComment", moduleHouse.getTableComment());
        return velocityContext;
    }

    /**
     * 构建渲染BasicDAO.java.vm需要的上下文
     */
    public static VelocityContext buildXBasicDAO(Module module) {
        VelocityContext velocityContext = new VelocityContext();
        velocityContext.put("packageName", module.getPackageName());
        return velocityContext;
    }

    public static VelocityContext buildXBasicService(ModuleHouse moduleHouse, Module module) {
        VelocityContext velocityContext = new VelocityContext();
        velocityContext.put("packageName", module.getPackageName());
        for (Module module1 : moduleHouse.getModules()) {
            if (module1.getModuleName().equalsIgnoreCase(ModuleConstants.BASIC_DAO)) {
                velocityContext.put("baseDaoImport", module1.getPackageName() + "." + module1.getFileName());
                break;
            }
        }
        return velocityContext;
    }

    /**
     * 构建渲染BasicMapper.xml.vm需要的上下文
     */
    public static VelocityContext buildXBasicMapper(Module module, ModuleHouse moduleHouse) {
        VelocityContext velocityContext = new VelocityContext();
        for (Module module1 : moduleHouse.getModules()) {
            if (module1.getModuleName().equalsIgnoreCase(ModuleConstants.BASIC_DOMAIN)) {
                velocityContext.put("DOPackageName", module1.getPackageName() + "." + module1.getFileName());
            }
            if (module1.getModuleName().equalsIgnoreCase(ModuleConstants.BASIC_DAO)) {
                velocityContext.put("DAOPackageName", module1.getPackageName() + "." + module1.getFileName());
            }
        }
        return velocityContext;
    }

    /**
     * 构建渲染Mapper_BASIC.xml.vm需要的上下文
     */
    public static VelocityContext buildXMapperBasic(ModuleHouse moduleHouse, Module module) {
        VelocityContext velocityContext = new VelocityContext();
        for (Module module1 : moduleHouse.getModules()) {
            if (module1.getModuleName().equalsIgnoreCase(ModuleConstants.DOMAIN_BASIC)) {
                velocityContext.put("do", module1.getPackageName() + "." + module1.getFileName());
            }
            if (module1.getModuleName().equalsIgnoreCase(ModuleConstants.DAO_BASIC)) {
                velocityContext.put("dao", module1.getPackageName() + "." + module1.getFileName());
            }
            if (module1.getModuleName().equalsIgnoreCase(ModuleConstants.BASIC_DAO)) {
                velocityContext.put("basicDAOPackageName", module1.getPackageName() + "." + module1.getFileName());
            }
        }
        velocityContext.put("tableName", moduleHouse.getTableName());
        velocityContext.put("columns", moduleHouse.getColumns());
        List<GenColumn> collect = MapUtils.filterBasicColumns(moduleHouse.getColumns());
        velocityContext.put("collect", collect);
        return velocityContext;
    }

    /**
     * 构建渲染Mapper_BASIC.xml.vm需要的上下文
     */
    public static VelocityContext buildXMapper(ModuleHouse moduleHouse, Module module) {
        VelocityContext velocityContext = new VelocityContext();
        for (Module module1 : moduleHouse.getModules()) {
            if (module1.getModuleName().equalsIgnoreCase(ModuleConstants.DOMAIN)) {
                velocityContext.put("do", module1.getPackageName() + "." + module1.getFileName());
            }
            if (module1.getModuleName().equalsIgnoreCase(ModuleConstants.DAO)
                    || module1.getModuleName().equalsIgnoreCase(ModuleConstants.DAO_BASIC)) {
                velocityContext.put("dao", module1.getPackageName() + "." + module1.getFileName());
            }
        }
        velocityContext.put("keyJdbcType", moduleHouse.getPrimaryKey().getJdbcType());
        velocityContext.put("keyClassType", moduleHouse.getPrimaryKey().getPropertyType());
        velocityContext.put("tableName", moduleHouse.getTableName());
        velocityContext.put("columns", moduleHouse.getColumns());
        velocityContext.put("commonColumns", moduleHouse.getCommonColumns());
        velocityContext.put("uniqueIndexs", moduleHouse.getUniqueIndexs());
        List<GenColumn> collect = MapUtils.filterBasicColumns(moduleHouse.getColumns());
        velocityContext.put("collect", collect);
        return velocityContext;
    }

}
